package com.beemans.corekit.integration.toolkit;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

final class UtilsActivityLifecycleImpl implements Application.ActivityLifecycleCallbacks {
    private final LinkedList<Activity> activityStack = new LinkedList<>();
    private final List<OnAppStatusChangedListener> mStatusListeners = new CopyOnWriteArrayList<>();

    private int mForegroundCount = 0;
    private int mConfigCount = 0;

    @Nullable
    private Boolean mIsBackground = null;

    private UtilsActivityLifecycleImpl() {
    }

    static final class Holder {
        static final UtilsActivityLifecycleImpl INSTANCE = new UtilsActivityLifecycleImpl();
    }

    void init(@NonNull Application application) {
        application.registerActivityLifecycleCallbacks(this);
    }

    void unInit(@NonNull Application application) {
        activityStack.clear();
        application.unregisterActivityLifecycleCallbacks(this);
    }

    @Nullable
    public Activity currentActivity() {
        return activityStack.isEmpty() ? null : activityStack.getFirst();
    }

    @NonNull
    public LinkedList<Activity> getActivityList() {
        return activityStack;
    }

    void registerAppStatusChangedListener(@NonNull OnAppStatusChangedListener listener) {
        mStatusListeners.add(listener);
    }

    void unregisterAppStatusChangedListener(@NonNull OnAppStatusChangedListener listener) {
        mStatusListeners.remove(listener);
    }

    @Override
    public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
        if (activityStack.isEmpty()) {
            postStatus(activity, true);
        }
        setTopActivity(activity);
    }

    @Override
    public void onActivityStarted(@NonNull Activity activity) {
        if (Boolean.FALSE.equals(mIsBackground)) {
            setTopActivity(activity);
        }
        if (mConfigCount < 0) {
            ++mConfigCount;
        } else {
            ++mForegroundCount;
        }
    }

    @Override
    public void onActivityResumed(@NonNull Activity activity) {
        setTopActivity(activity);

        if (Boolean.TRUE.equals(mIsBackground)) {
            postStatus(activity, true);
        }
    }

    @Override
    public void onActivityPaused(@NonNull Activity activity) {
    }

    @Override
    public void onActivityStopped(@NonNull Activity activity) {
        if (activity.isChangingConfigurations()) {
            --mConfigCount;
        } else {
            --mForegroundCount;

            if (mForegroundCount <= 0) {
                postStatus(activity, false);
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
    }

    @Override
    public void onActivityDestroyed(@NonNull Activity activity) {
        activityStack.remove(activity);
    }

    private void setTopActivity(Activity activity) {
        if (activityStack.contains(activity)) {
            if (!activityStack.getFirst().equals(activity)) {
                activityStack.remove(activity);
                activityStack.addFirst(activity);
            }
        } else {
            activityStack.addFirst(activity);
        }
    }

    private void postStatus(final Activity activity, final boolean isForeground) {
        mIsBackground = !isForeground;

        if (mStatusListeners.isEmpty()) {
            return;
        }
        for (OnAppStatusChangedListener statusListener : mStatusListeners) {
            if (isForeground) {
                statusListener.onForeground(activity);
            } else {
                statusListener.onBackground(activity);
            }
        }
    }
}